'''
Created on Feb 25, 2012

@author: daoxuandung
'''

from google.appengine.api import taskqueue
import webapp2
from webapp2_extras import auth
from webapp2_extras import sessions
from uuid import uuid4
import urllib
from kid import util
import logging
import json

        
def user_required(handler):
    """
    Decorator for checking if there's a user associated with the current session.
    Will redirect to login page for normal HTTP Request
    For AJAX request, it only returns the 401 - Unauthorized status code
    """
    def check_login(self, *args, **kwargs):
        if not util.get_current_user_key():
            self.abort(401)
        else:
            return handler(self, *args, **kwargs)

    return check_login


class BaseHandler(webapp2.RequestHandler):
    """
    BaseHandler for all requests
    Holds the auth and session properties so they are reachable for all requests
     """

    def dispatch(self):
        """
        Save the sessions for preservation across requests
        """
        try:
            self.csrf_protect = False
            self.init_csrf()
            super(BaseHandler, self).dispatch()
        finally:
            self.session_store.save_sessions(self.response)
    
    # CSRF protection        
    def init_csrf(self):
        """
        Issue and handle CSRF token as necessary
        """
        self.csrf_token = self.request.cookies.get('csrf')
        if not self.csrf_token:
            self.csrf_token = str(uuid4())[:8]
            self.response.set_cookie('csrf', self.csrf_token, httponly=True)
        
        if self.request.method == 'POST' and self.csrf_protect \
            and self.csrf_token != self.request.get('_csrf_token'):
            self.abort(403)


    # Authentication
    @webapp2.cached_property
    def auth(self):
        return auth.get_auth()

    @webapp2.cached_property
    def session_store(self):
        return sessions.get_store(request=self.request)

    @webapp2.cached_property
    def auth_config(self):
        """
              Dict to hold urls for login/logout
          """
        return {
            'login_url': self.uri_for('login'),
            'logout_url': self.uri_for('logout')
        }
        
    def login(self, user, remember=False):
        """
        user should be webapp2_extras.appengine.auth.models.User
        """
        user_dict = self.auth.store.user_to_dict(user)
        self.auth.set_session(user_dict, remember=remember)
        
        payload = {}
        payload['user_id'] = str(util.get_current_user_key().id())
        logging.info(payload)
        taskqueue.Task(url=webapp2.uri_for('cron-user-setup'), params=payload).add()